#ifndef SIMULATION_CORE_GDC_H
#define SIMULATION_CORE_GDC_H

#include <SimulationCore/Core.h>
#include <vector>
namespace SimulationCore
{
    class GCC;
    class GDC
    {
        public:
        GDC()
        :m_longitude(0),m_latitude(0),m_altitude(0)
        {
            
        }

        GDC(double longitude, double latitude)
        :m_longitude(longitude),m_latitude(latitude),m_altitude(0)
        {
            
        }


        GDC(double longitude, double latitude,double altitude)
        :m_longitude(longitude),m_latitude(latitude),m_altitude(altitude){}


        GDC operator+(const GDC& gdc) const
        {
            return GDC(m_longitude+gdc.m_longitude,m_latitude+gdc.m_latitude,m_altitude+gdc.m_altitude);
        }

        GDC operator-(const GDC& gdc) const
        {
            return GDC(m_longitude-gdc.m_longitude,m_latitude-gdc.m_latitude,m_altitude-gdc.m_altitude);
        }

        GDC operator*(double scale) const
        {
            return GDC(m_longitude*scale,m_latitude*scale,m_altitude*scale);
        }

        GDC operator/(double scale) const
        {
            return GDC(m_longitude/scale,m_latitude/scale,m_altitude/scale);
        }

        GDC operator*(const GDC& gdc) const
        {
            return GDC(m_longitude*gdc.m_longitude,m_latitude*gdc.m_latitude,m_altitude*gdc.m_altitude);
        }

        GDC operator/(const GDC& gdc) const
        {
            return GDC(m_longitude/gdc.m_longitude,m_latitude/gdc.m_latitude,m_altitude/gdc.m_altitude);
        }

        GDC& operator+=(const GDC& gdc)
        {
            m_longitude+=gdc.m_longitude;
            m_latitude+=gdc.m_latitude;
            m_altitude+=gdc.m_altitude;
            return *this;
        }

        GDC& operator-=(const GDC& gdc)
        {
            m_longitude-=gdc.m_longitude;
            m_latitude-=gdc.m_latitude;
            m_altitude-=gdc.m_altitude;
            return *this;
        }

        double dot(const GDC& v) const
        {
            return m_longitude * v.m_longitude + m_latitude * v.m_latitude + m_altitude * v.m_altitude;
        }

        GDC cross(const GDC& v) const
        {
            return GDC(m_latitude * v.m_altitude - m_altitude * v.m_latitude, m_altitude * v.m_longitude - m_longitude * v.m_altitude, m_longitude * v.m_latitude - m_latitude * v.m_longitude);
        }

        double length() const
        {
            return sqrt(m_longitude * m_longitude + m_latitude * m_latitude + m_altitude * m_altitude);
        }

        double distance(const GDC& v) const
        {
            return sqrt((m_longitude - v.m_longitude) * (m_longitude - v.m_longitude) + (m_latitude - v.m_latitude) * (m_latitude - v.m_latitude) + (m_altitude - v.m_altitude) * (m_altitude - v.m_altitude));
        }

        GCC toGCC(bool isEllipsoid = true) const;

        CLASS_PARAMS_PUBLIC(double,m_longitude,lon);
        CLASS_PARAMS_PUBLIC(double,m_latitude,lat);
        CLASS_PARAMS_PUBLIC(double,m_altitude,alt);
    };
    typedef std::vector<GDC> GDCVector;
}

#endif